
package com.meme.editor.level;

import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.BasicStroke;
import java.awt.Rectangle;
import java.awt.Color;
import java.util.ListIterator;

import com.meme.editor.Box2d;
import com.meme.editor.PropertyValueModification;
import com.meme.editor.PropertyValueModificationList;
import com.meme.editor.level.define.DefineFile;
import com.meme.editor.model.sprite2d.AnimatedModule;
import com.meme.editor.model.sprite2d.AnimatedModuleGroup;
import com.meme.editor.property.PropertyFactory;
import com.meme.io.editor.FileCache;
import com.meme.util.FileUtil;
import com.meme.util.MiscUtil;

public class Line2dAppearance extends Appearance 
{
	public static final String ParamName_Color = "color";
	public static final String ParamName_Point1X = "point1_x";
	public static final String ParamName_Point1Y = "point1_y";
	public static final String ParamName_Point2X = "point2_x";
	public static final String ParamName_Point2Y = "point2_y";
	public static final String ParamName_Thickness = "thickness";
	public static final String ParamName_StartColor = "start_color";
	public static final String ParamName_EndColor = "end_color";
	public static final String ParamName_StartRadius = "start_radius";
	public static final String ParamName_EndRadius = "end_radius";
	
	
	final static String GroupName_BoxGroup = "Line2d Properties";
	final static String PropertyName_Point1X       = "Point1 X";
	final static String PropertyName_Point1Y       = "Point1 Y";
	final static String PropertyName_Point2X       = "Point2 X";
	final static String PropertyName_Point2Y       = "Point2 Y";

	
	Color mColor = new Color (0);
	Color mStartColor = new Color (0);
	Color mEndColor = new Color (0);
	
	int mLineThickness = 1;
	int mStartRadius = 2;
	int mEndRadius = 2;
	
	int mPoint1X = 0;
	int mPoint1Y = 0;
	int mPoint2X = 0;
	int mPoint2Y = 0;
	
	boolean mRelativeToActor = true;
	boolean mApplyActorScaleAndFlips = false;
	
	public Line2dAppearance ()
	{
		super ();
		
		createPropertyGroup (GroupName_BoxGroup);
		createPublicProperty (GroupName_BoxGroup, PropertyName_Point1X, PropertyFactory.ValueType_Number);
		createPublicProperty (GroupName_BoxGroup, PropertyName_Point1Y, PropertyFactory.ValueType_Number);
		createPublicProperty (GroupName_BoxGroup, PropertyName_Point2X, PropertyFactory.ValueType_Number);
		createPublicProperty (GroupName_BoxGroup, PropertyName_Point2Y, PropertyFactory.ValueType_Number);
	}

	@Override
	protected void _handleModifyingPropertyValues (PropertyValueModificationList modications)
	{			
		super._handleModifyingPropertyValues (modications);
		
		ListIterator<PropertyValueModification> iter = modications.listIterator();
		while ( iter.hasNext() )
		{
			PropertyValueModification mod = iter.next();
			
			if ( mod.mGroupName.equals (GroupName_BoxGroup) )
			{
				boolean handled = true;
				if ( mod.mPropertyName.equals (PropertyName_Point1X) )
				{
					SetPoint1X (( (Float) (mod.mNewValue) ).intValue());
				}
				else if ( mod.mPropertyName.equals (PropertyName_Point1Y) )
				{
					SetPoint1Y (( (Float) (mod.mNewValue) ).intValue());
				}
				else if ( mod.mPropertyName.equals (PropertyName_Point2X) )
				{
					SetPoint2X (( (Float) (mod.mNewValue) ).intValue());
				}
				else if ( mod.mPropertyName.equals (PropertyName_Point2Y) )
				{
					SetPoint2Y (( (Float) (mod.mNewValue) ).intValue());
				}
				else
					handled = false;
				
				if (handled)
					iter.remove();
			}
		}
	}	
	
	@Override
	public void setParameter (String paramName, String paramValue)
	{
		if ( paramName.equals (ParamName_Color) )
		{
			mColor = MiscUtil.parseColor(paramValue, 0x0);
		}
		else if (paramName.equals(ParamName_Point1X))
		{
			SetPoint1X ( MiscUtil.parseInt(paramValue, 0x0) );
		}
		else if (paramName.equals(ParamName_Point1Y))
		{
			SetPoint1Y ( MiscUtil.parseInt(paramValue, 0x0) );
		}
		else if (paramName.equals(ParamName_Point2X))
		{
			SetPoint2X ( MiscUtil.parseInt(paramValue, 0x0) );
		}
		else if (paramName.equals(ParamName_Point2Y))
		{
			SetPoint2Y ( MiscUtil.parseInt(paramValue, 0x0) );
		}
		else if (paramName.equals(ParamName_Thickness))
		{
			mLineThickness = MiscUtil.parseInt(paramValue, 1);
			if (mLineThickness < 1)
				mLineThickness = 1;
		}
		else if (paramName.equals(ParamName_StartRadius))
		{
			mStartRadius = MiscUtil.parseInt(paramValue, 0);
		}
		else if (paramName.equals(ParamName_EndRadius))
		{
			mEndRadius = MiscUtil.parseInt(paramValue, 0);
		}
		else if (paramName.equals(ParamName_StartColor))
		{
			mStartColor = MiscUtil.parseColor(paramValue, 0x0);
		}
		else if (paramName.equals(ParamName_EndColor))
		{
			mEndColor = MiscUtil.parseColor(paramValue, 0x0);
		}
	}


	public void SetPoint1X (int x)
	{
		mPoint1X = x;

		changePublicPropertyValue (GroupName_BoxGroup, PropertyName_Point1X, mPoint1X);
	}
	
	public int getPoint1X ()
	{
		return mPoint1X;
	}

	public void SetPoint1Y (int y)
	{
		mPoint1Y = y;

		changePublicPropertyValue (GroupName_BoxGroup, PropertyName_Point1Y, mPoint1Y);
	}
	
	public int getPoint1Y ()
	{
		return mPoint1Y;
	}

	public void SetPoint2X (int x)
	{
		mPoint2X = x;

		changePublicPropertyValue (GroupName_BoxGroup, PropertyName_Point2X, mPoint2X);
	}
	
	public int getPoint2X ()
	{
		return mPoint2X;
	}

	public void SetPoint2Y (int y)
	{
		mPoint2Y = y;

		changePublicPropertyValue (GroupName_BoxGroup, PropertyName_Point2Y, mPoint2Y);
	}
	
	public int getPoint2Y ()
	{
		return mPoint2Y;
	}

//	@Override
//	public void show (Graphics2D g, int posX, int posY, boolean flipX, boolean flipY, int scale, int flag)
//	{
//		Color oldColor = g.getColor ();
//
//		if (mFilledColor != null)
//		{
//			g.setColor (mFilledColor);
//			g.fillRect(posX + mLeft, posY + mTop, mRight - mLeft, mBottom - mTop);
//		}
//		
//		g.setColor (mBorderColor);
//		g.drawRect(posX + mLeft, posY + mTop, mRight - mLeft, mBottom - mTop);
//		
//		g.setColor (oldColor);
//	}

	@Override
	public void show (Graphics2D g, int flag)
	{
		Color oldColor = g.getColor ();
		Stroke oldStroke = g.getStroke();

		g.setColor (mColor);
		g.setStroke(new BasicStroke(mLineThickness)); 
		g.drawLine (mPoint1X, mPoint1Y, mPoint2X, mPoint2Y);
		g.setStroke (oldStroke);
		
		if (mStartRadius > 0)
		{
			g.setColor (mStartColor);
			g.fillArc(mPoint1X - mStartRadius, mPoint1Y - mStartRadius, mStartRadius + mStartRadius, mStartRadius + mStartRadius, 0, 360);
			g.setColor (new Color(0));
			g.drawArc(mPoint1X - mStartRadius, mPoint1Y - mStartRadius, mStartRadius + mStartRadius, mStartRadius + mStartRadius, 0, 360);
		}
		
		if (mEndRadius > 0)
		{
			g.setColor (mEndColor);
			g.fillArc(mPoint2X - mEndRadius, mPoint2Y - mEndRadius, mEndRadius + mEndRadius, mEndRadius + mEndRadius, 0, 360);
			g.setColor (new Color(0));
			g.drawArc(mPoint2X - mEndRadius, mPoint2Y - mEndRadius, mEndRadius + mEndRadius, mEndRadius + mEndRadius, 0, 360);
		}
		
		
		g.setColor (oldColor);
		
	}

	@Override
	public void getBoundingBox (Box2d box2d)
	{
		box2d.set (mPoint1X, mPoint1Y, mPoint2X, mPoint2Y);
		if (box2d.right - box2d.left < 1)
		{
			box2d.left  -= mLineThickness;
			box2d.right += mLineThickness;
		}
		if (box2d.bottom - box2d.top < 1)
		{
			box2d.top  -= mLineThickness;
			box2d.bottom += mLineThickness;
		}
		
//		Actor actor = (Actor) getParent ();
//		if (mApplyActorScaleAndFlips)
//			box2d.adjust (actor.isFlipX (), actor.isFlipY ());
//		if (mRelativeToActor)
//			box2d.shift(actor.getPosX(), actor.getPosY());
	}
	
	
	@Override
	public boolean isGeometryAppearance ()
	{
		return true;
	}
}
